<?php
/**
 * model Class
 *
 * Main class for model, used to perform common CRUD operation on the database tables
 * Maps a table of the database to an Associative array representing the model object.
 *
 * @author Victor Nava
 *
 */

class model {
	public $dbCon;
	public $tableName;
	public $tableCols;
	public $pageSize = 10;
	public $tableKey = "id";

	/**
	 * Constructor
	 *
	 * @param $tableName table associated with the model
	 * @return Associative Array Attributes and Values of table
	 */
	function __construct($tableName){
		try{
			$this->tableName = $tableName;
			$this->dbCon = DB::PDOConnection();
			$this->dbCon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			$this->tableCols = $this->getTableColumns($this->tableName);
		} catch(Exception $e){
			//TODO
			echo 'Error connecting to DB ' , $e->getMessage();
			exit;
		}
	}

		
	/**
	 * Gets a single record from the db by id
	 * @param $id
	 * @return Associative Array Attributes and Values of table
	 */
	function get($id){
		//TODO parameters and values shuold be passed as argument
		//so that for example get by name should be posible

		$sql = "SELECT * FROM $this->tableName WHERE id=:id";
		try{
			$stmt = $this->dbCon->prepare($sql);
			$params = array(':id'=>$id);
			$stmt->execute($params);
			return $stmt->fetch(PDO::FETCH_ASSOC);
		}catch (PDOException $e){
			//TODO find proper way to display message?
			echo $e;
			return null;
		}
	}

	/**
	 * Gets all the records of a table
	 * 
	 * @param $args page
	 * @return Associative Array Attributes and Values of table
	 */
	function getAll($args = null){

		$sql = "SELECT * FROM $this->tableName";

		if(isset($args['page'])){
			//echo 'page set';
			$page = (int)$args['page'];
			$from = $page * $this->pageSize;
			$sql = "SELECT * FROM $this->tableName LIMIT $from, $this->pageSize";
		}

		try{
			return $this->dbCon->query($sql)->fetchAll(PDO::FETCH_ASSOC);
		}catch (PDOException $e){
			//TODO find proper way to display message?
			echo $e;
			return null;
		}
	}

	/**
	 * Creates a record in the table
	 * 
	 * @param $args
	 * @return Associative Array Attributes and Values of created record
	 */
	function create($args=null){

		//TODO check if already exist

		if(!isset($args)){
			return false;
		}

		//TODO make function get colVals;
		foreach($args as $col=>$val){
			if($col != 'id'){
				if(in_array($col, $this->tableCols)){
					$columns[] = $col;
					$values[] = is_numeric($val) ? $val : "'".$val."'";
				}
			}
		}

		if(!isset($columns)){
			return false;
		}

		$sqlInsert = "INSERT INTO ".$this->tableName." (".implode(",", $columns) . ') VALUES ('.implode(",", $values).')';
		$sqlLast = "SELECT * FROM $this->tableName ORDER BY $this->tableKey DESC LIMIT 1";
		//echo $sqlLast;

		try{
			//TODO this should be a transaction
			$rowCount = $this->dbCon->exec($sqlInsert);
			if($rowCount < 1){
				return false;
			}
			return $this->dbCon->query($sqlLast)->fetchAll(PDO::FETCH_ASSOC);
		}catch (PDOException $e){
			//TODO find proper way to display message?
			echo $e->getMessage();
		}
	}

	/**
	 * Updates a record in the table
	 * 
	 * @param $args
	 * @return Associative Array Attributes and Values of updated record
	 */
	function update($args=null){

		if(!isset($args) || !isset($args['id'])){
			return false;
		}
	
		foreach($args as $col=>$val){
			if($col != 'id'){
				if(in_array($col, $this->tableCols)){
					$colsAndVals[] = $col .'=' . (is_numeric($val) ? $val : "'".$val."'");
				}
			}
		}

		if(!isset($colsAndVals)){
			return false;
		}

		$id = $args['id'];
		$colsAndValsStr = implode(',', $colsAndVals);
		$table = $this->tableName;
			
		$sql = "UPDATE $table SET $colsAndValsStr WHERE (id=$id)";

		try{
			return $this->dbCon->exec($sql);
		}catch (PDOException $e){
			//TODO find proper way to display message?
			echo $e->getMessage();
		}
	}

	function delete($id){
		//TODO implement
	}

	
	/**
	 * Get all the columns name of the table
	 * @param $tableName
	 * @return Array Names of columns
	 */
	function getTableColumns($tableName){
		//echo "getTableColumns($tableName)";
		$desc = $this->dbCon->query("DESCRIBE $tableName")->fetchAll(PDO::FETCH_ASSOC);
		$cols = array();
		foreach($desc as $cd){
			$cols[] = $cd['Field'];
		}
		return $cols;
	}
}
?>